#!/usr/bin/python3
# coding=utf-8

import collections
from functools import reduce
import sys
import os.path
import re
import json
import random
import operator
#import requests


def exectue_cmd(command):
    command=command.replace("\n", "")
    command_fd = os.popen(command, "r")
    ret = command_fd.read()
    command_fd.close()
    return ret

def stack(name, file):
    fd = open(file,"r")
    satck_str = fd.read().split("-----")
    for i, ek in enumerate(satck_str):
        if name in satck_str[i]:
            result = ek
            fd.close()
            return result
    fd.close()

def cpuflamegraph(file):
    fd = open(file,"r")
    graph = fd.read().split("####################################################################################")
    if len(graph) >= 3:
        return graph[2]
    else:
        return "无法生成火焰图"
    fd.close()

def parse_log(file):
    parse_data=collections.OrderedDict()
    new_parse_data=collections.OrderedDict()
    reason=collections.OrderedDict()
    tasks = {}
    count = {}
    task_stack = {}
    d_task_list = []
    r_task_list = []
    cpuflamegraph_str = ""

    fd = open(file,"r")
    for line in fd.readlines():
        if "global_cpuflamegraph" in line:
            cpuflamegraph_str = cpuflamegraph(file)
            continue
        if "load reason" in line:
            if "sys" in line:
                reason["sys"] = "true"
            else:
                reason["sys"] = "false"
            if "irq" in line:
                reason["irq"] = "true"
            else:
                reason["irq"] = "false"
            if "softirq" in line:
                reason["softirq"] = "true"
            else:
                reason["softirq"] = "false"
            if "io" in line:
                reason["io"] = "true"
            else:
                reason["io"] = "false"
            continue
        if "load_proc" in line:
                reason["loadavg"] =  line.split()[1]
        if "Task_Name" in line:
            task_name = re.search( r'Task_Name:	*(\S+)', line, re.I)
            if task_name:
                if task_name.group(1) in tasks:               
                    tasks[task_name.group(1)] = tasks[task_name.group(1)] + 1
                else:
                    tasks[task_name.group(1)] = 1
                if "[<0>]" in stack(task_name.group(1),file):
                    task_stack[task_name.group(1)] = stack(task_name.group(1),file)
            continue
        if "Time" in line:
            time = re.search( r'Time: (.+)', line, re.I)
            if time:
                time_str = time.group(1)
            continue
        if "uninterrupt_cnt" in line:
            count["uninterrupt tasks"]=line.split()[1]
            continue
        if "running_cnt" in line:
            count["runnig tasks"]=line.split()[1]
            continue     
    fd.close()
    task_sort = sorted(tasks.items(), key = lambda kv:kv[1],reverse=True)
    stack_sort = sorted(task_stack.items(), key = lambda kv:kv[1],reverse=True)
    for i, el in enumerate(task_sort):
        is_dtask=False
        for j, ek in enumerate(stack_sort):
            if el[0] == ek[0]:
                d_task = {}
                d_task["task"] = el[0]
                d_task["weight"] = el[1]
                d_task["stack"] = reduce(operator.add,ek[1].split("[<0>] ")[1:-1],' ')
                d_task_list.append(d_task)
                is_dtask=True
        if not is_dtask:
            r_task = {}
            r_task["task"] = el[0]
            r_task["weight"] = el[1]
            r_task_list.append(r_task)
    parse_data["result"] = reason
    parse_data["task_count"] =count
    parse_data["uninterrupt load"] = d_task_list
    parse_data["running load"] = r_task_list
    parse_data["flamegraph"] = cpuflamegraph_str

    new_parse_data["dataresult"] = {"data": {}}
    new_parse_data["dataresult"]["data"] = [
        {"key": "系统平均负载", "value": reason["loadavg"]},
        {"key": "Sys影响检测", "value": reason["sys"]},
        {"key": "硬件中断影响检测", "value": reason["irq"]},
        {"key": "软中断影响检测", "value": reason["softirq"]},
        {"key": "IO影响检测", "value": reason["io"]}
    ]

    new_parse_data["datataskcount"] = {"data": []}
    new_parse_data["datataskcount"]["data"] = [
        {"key": "uninterrupt_tasks", "value": int(count["uninterrupt tasks"])},
        {"key": "runnig_tasks", "value": int(count["runnig tasks"])},
    ]
    new_parse_data["datataskcount"]["data"]

    new_parse_data["datauninterruptload"] = {"data": []}
    for i in range(len(d_task_list)):
        tmp_d_task = {}
        tmp_d_task["key"] = d_task_list[i]["task"]
        tmp_d_task["value"] = d_task_list[i]["weight"]
        new_parse_data["datauninterruptload"]["data"].append(tmp_d_task)

    new_parse_data["datarunningload"] = {"data": []}
    for i in range(len(r_task_list)):
        tmp_r_task = {}
        tmp_r_task["key"] = r_task_list[i]["task"]
        tmp_r_task["value"] = r_task_list[i]["weight"]
        new_parse_data["datarunningload"]["data"].append(tmp_r_task)

    new_parse_data["dataflamegraph"] = {"data": []}
    new_parse_data["dataflamegraph"]["data"]= [
        {"key": 0, "value": cpuflamegraph_str}]
    out = json.dumps(new_parse_data, indent=4)
    #data = {"catalogue": parse_data["Global lamegraph"]}
    #files = {"file": open(parse_data["Global lamegraph"], 'rb')}
    #requests.post("http://127.0.0.1:8001/api/v1/host/upload_file/", data=data, files=files)
    print(out)

if __name__ == '__main__':
    parse_log(sys.argv[1])
